package com.timguan.render.web.controller;

import com.timguan.render.web.common.DefaultServiceErrorListener;
import com.timguan.render.web.common.ServiceExceptionListener;
import net.pocrd.entity.ServiceException;
import net.pocrd.entity.ServiceRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by guankaiqiang on 2014/12/3.
 */
public abstract class BaseController {
    private static final Logger                         logger                         = LoggerFactory.getLogger(BaseController.class);
    private              List<ServiceExceptionListener> serviceExceptionListeners      = new ArrayList<ServiceExceptionListener>();
    private static final DefaultServiceErrorListener DEFAULT_SERVICE_ERROR_LISTENER = new DefaultServiceErrorListener();

    protected void setServiceExceptionListeners(List<ServiceExceptionListener> listener) {
        if (listener != null) {
            serviceExceptionListeners.addAll(listener);
        }
    }

    @PostConstruct
    public void init() {
        initServiceExceptionListener();
    }

    public abstract void initServiceExceptionListener();

    @ExceptionHandler({ ServiceException.class, ServiceRuntimeException.class })
    public ModelAndView serviceExceptionHanlder(HttpServletRequest request, HttpServletResponse response, Exception exception) {
        if (serviceExceptionListeners != null && serviceExceptionListeners.size() != 0) {
            if (exception instanceof ServiceException) {
                ServiceException se = (ServiceException)exception;
                for (ServiceExceptionListener listener : serviceExceptionListeners) {
                    if (listener.accept(se.getCode())) {
                        return listener.serviceExceptionEventHandle(se.getCode(), se, null, request, response);
                    }
                }
            } else if (exception instanceof ServiceRuntimeException) {
                ServiceRuntimeException se = (ServiceRuntimeException)exception;
                for (ServiceExceptionListener listener : serviceExceptionListeners) {
                    if (listener.accept(se.getCode())) {
                        return listener.serviceExceptionEventHandle(se.getCode(), null, se, request, response);
                    }
                }
            }
        }
        if (exception instanceof ServiceException) {
            ServiceException se = (ServiceException)exception;
            logger.error("api异常，error code:{},msg:{}", se.getCode(), se.getMsg());
            return DEFAULT_SERVICE_ERROR_LISTENER.serviceExceptionEventHandle(se.getCode(), se, null, request, response);
        } else if (exception instanceof ServiceRuntimeException) {
            ServiceRuntimeException se = (ServiceRuntimeException)exception;
            logger.error("api异常，error code:{},msg:{}", se.getCode(), se.getMsg());
            return DEFAULT_SERVICE_ERROR_LISTENER.serviceExceptionEventHandle(se.getCode(), null, se, request, response);
        } else {
            logger.error("api异常", exception);
            return null;
        }
    }
}
